package com.atguigu.juc.interview.cf;

import lombok.Getter;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author : leimingchao
 * @date Date : 2021年10月01日 11:03
 */
public class CompletableFutureNetMallDemo2 {

    static List<NetMall> list = Arrays.asList(
            new NetMall("jd"),
            new NetMall("pdd"),
            new NetMall("taobao"),
            new NetMall("dangdangwang"),
            new NetMall("tmall")

    );

    /**
     * 同步，step by step
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPriceByStep(List<NetMall> list, String productName) {
        return list.stream()
                .map(item -> String.format(productName + " in %s price is %.2f", item.getMallName(), item.calcPrice(productName)))
                .collect(Collectors.toList());
    }

    /**异步，多箭齐发
     * List<NetMall>  -----> List<CompletableFuture<String> -----> List<String>
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPriceByAsyc(List<NetMall> list, String productName) {

        return list.stream()
                .map(item -> CompletableFuture.supplyAsync(() -> String.format(productName + " in %s price is %.2f", item.getMallName(), item.calcPrice(productName))))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {

        LocalDateTime start = LocalDateTime.now();
        List<String> list1 = getPriceByStep(list, "mysql");
        list1.stream().forEach(System.out::println);
        LocalDateTime end = LocalDateTime.now();

        System.out.println("----costTime:" + Duration.between(start,end).getSeconds() + "秒");
        System.out.println();

        LocalDateTime start2 = LocalDateTime.now();
        List<String> list2 = getPriceByAsyc(list, "mysql");
        list2.stream().forEach(System.out::println);
        LocalDateTime end2 = LocalDateTime.now();

        System.out.println("----costTime:" + Duration.between(start2,end2).getSeconds() + "秒");
    }
}


class NetMall {


    @Getter
    private String mallName;

    public NetMall(String mallName) {
        this.mallName = mallName;
    }

    public double calcPrice(String productName) {

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
    }
}